package jaygoo.library.m3u8downloader;

import android.text.TextUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.MessageDigest;

import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import jaygoo.library.m3u8downloader.utils.AES128Utils;
import jaygoo.library.m3u8downloader.utils.M3U8Log;

import static jaygoo.library.m3u8downloader.utils.AES128Utils.parseByte2HexStr;
import static jaygoo.library.m3u8downloader.utils.AES128Utils.parseHexStr2Byte;
import static jaygoo.library.m3u8downloader.utils.MUtils.readFile;
import static jaygoo.library.m3u8downloader.utils.MUtils.saveFile;

/**
 * ================================================
 * 作    者：JayGoo
 * 版    本：
 * 创建日期：2017/11/27
 * 描    述: M3U8加密助手类
 * ================================================
 */
public class M3U8EncryptHelper {

    private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
    private static final int KEY_SIZE = 128;
    private static final int CACHE_SIZE = 1024;
    private static final String SECRET_KEY = "ceb4623299dba9e8";
    /**
     * <p>
     * 文件解密
     * </p>
     *
     * @param sourceFilePath
     * @param destFilePath
     * @throws Exception
     */
    public static void decryptFileUniversal(String iv, String key,String sourceFilePath, String destFilePath) throws Exception {
//        if (TextUtils.isEmpty(key)){
//            key = SECRET_KEY;
//        }
       M3U8Log.d("秘钥对比key:"+key.trim().length()+ "_SECRET_KEY:"+SECRET_KEY.length()+"  result:"+key.equals(SECRET_KEY));
//        String md5 = MD5(key+iv).toUpperCase();
//        key = md5.substring(0,16);
//        iv = md5.substring(16);
        File sourceFile = new File(sourceFilePath);
        File destFile = new File(destFilePath);
        if (sourceFile.exists() && sourceFile.isFile()) {
            if (!destFile.getParentFile().exists()) {
                destFile.getParentFile().mkdirs();
            }
            destFile.createNewFile();
            FileInputStream in = new FileInputStream(sourceFile);
            FileOutputStream out = new FileOutputStream(destFile);
            SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "AES");
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec,ivParameterSpec);
            CipherOutputStream cout = new CipherOutputStream(out, cipher);
            byte[] cache = new byte[CACHE_SIZE];
            int nRead = 0;
            while ((nRead = in.read(cache)) != -1) {
                cout.write(cache, 0, nRead);
                cout.flush();
            }
            cout.close();
            out.close();
            in.close();
        }
    }

    /**
     * md5加密算法
     * @param value 欲使用md5算法加密的字符串
     * @return String 已经使用md5算法加密后的字符串
     */
    public static String MD5(String value) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(value.getBytes("UTF8"));
            byte s[] = md.digest();
            String result = "";
            for (int i = 0; i < s.length; i++) {
                result += Integer.toHexString( (0x000000FF & s[i]) | 0xFFFFFF00).substring(6);
            }
            return result;
        } catch (Exception e) {
            return null;
        }
    }

    public static void encryptFile(String key, String fileName) throws Exception{
        if (TextUtils.isEmpty(key)) return;
        byte[] bytes = AES128Utils.getAESEncode(key,readFile(fileName));
        saveFile(bytes, fileName);
    }

    public static void decryptFile(String key, String fileName) throws Exception{
        if (TextUtils.isEmpty(key)) return;
        byte[] bytes = AES128Utils.getAESDecode(key,readFile(fileName));
        saveFile(bytes, fileName);

    }


    /**
     * 加密文件
     * @param key
     * @param str
     * @return
     * @throws Exception
     */
    public static String encryptFileName(String key, String str) throws Exception{
        M3U8Log.d("加密文件名_encryptFileName:"+str);
        if (TextUtils.isEmpty(key)) return str;
        str = parseByte2HexStr(AES128Utils.getAESEncode(key,str));
        return str;
    }

    /**
     * 解密文件
     * @param key
     * @param str
     * @return
     * @throws Exception
     */
    public static String decryptFileName(String key, String str) throws Exception{
        M3U8Log.d("解密文件_decryptFileName_key:"+key+"_"+str);
        if (TextUtils.isEmpty(key)) return str;
        str = new String(AES128Utils.getAESDecode(key,parseHexStr2Byte(str)));
        return str;
    }

    public static void encryptTsFilesName(String key, String dirPath) throws Exception{
        M3U8Log.d("加密ts文件名_encryptTsFilesName key:"+key+"_"+dirPath);
        if (TextUtils.isEmpty(key)) return;
        File dirFile = new File(dirPath);
        if (dirFile.exists() && dirFile.isDirectory()){
            File[] files = dirFile.listFiles();
            for (int i = 0; i < files.length; i++) {// 遍历目录下所有的文件
                if (files[i].getName().contains("m3u8"))continue;
                File renameFile = new File(dirPath, encryptFileName(key, files[i].getName()));
                files[i].renameTo(renameFile);
            }
        }

    }

    public static void decryptTsFilesName(String key, String dirPath) throws Exception{
        M3U8Log.d("解密ts文件名_encryptTsFilesName key:"+key+"_"+dirPath);

        if (TextUtils.isEmpty(key)) return ;
        File dirFile = new File(dirPath);
        if (dirFile.exists() && dirFile.isDirectory()){
            File[] files = dirFile.listFiles();
            for (int i = 0; i < files.length; i++) {// 遍历目录下所有的文件
                if (files[i].getName().contains("m3u8"))continue;
//                File renameFile = new File(dirPath,decryptFileName(key, files[i].getName()));
                File renameFile = new File(dirPath,files[i].getName());
                files[i].renameTo(renameFile);
                M3U8Log.e(dirPath+"开始对文件进行解密 :"+renameFile.getAbsolutePath());
                M3U8EncryptHelper.decryptFile("ceb4623299dba9e8",renameFile.getAbsolutePath());
            }
        }
    }
}
